package shapewar.engine.model;

import shapewar.conf.Conf;
import shapewar.engine.calc.Pos;
import shapewar.engine.ext.Animation;
import shapewar.engine.ext.SkillColder;
import shapewar.engine.intefac.IHittable;
import shapewar.engine.intefac.ITank;
import shapewar.engine.intefac.Regedit;
import shapewar.engine.model.abst.ModelAdapter;
import shapewar.engine.presenter.Presenter;
import shapewar.media.Media;
import shapewar.net.client.User;
import shapewar.view.myview.MyButton;
import shapewar.view.tank.ProtectorView;

public class Tank extends ModelAdapter implements ITank{
	public Wall wall;
	protected Protector protector;
	private boolean isAlive = false;
	protected SkillColder sc = new SkillColder(this);
	private User user;
	public Tank(Presenter pst, int id, float x, float y, float[][] v) {
		super(pst, id, x, y, v, Conf.depth_tank);
	}
	
	@Override
	public void init() {
		speed = Conf.tank_speed;
		pst.bridge.addView(pst.bridge.createTankView(this));
		protector = new Protector(pst,this);
		protector.init();
		pst.regist(this, Regedit.ITank,Regedit.IView,Regedit.IRepeat4Tank);
		sc.supertime();
		isAlive = true;
	}
	
	public void setUser(User user){
		this.user = user;
		getProtector().plus(user.info.protector_num-Conf.protector_init_count);
	}
	
	public User getUser(){
		return this.user;
	}
	
	public boolean isInSuperTime(){
		return sc.super_time;
	}
	
	@Override
	public void destory() {
		pst.registoff(this, Regedit.ITank,Regedit.IView,Regedit.IRepeat4Tank);
		protector.destory();
		pst.bridge.removeView(getView());
	}
	
	@Override
	public void die() {
		if(pst.ect.player!=null && isAlive)
			Media.boom(calcer.calcDistance(getPos(), pst.ect.player.getPos()),Conf.visible_area_radium);
		destory();
		isAlive = false;
	}
	
	public void die(Tank killer, int bulletKey,int ptrNum){
		die();
		
		//Protector Fade to killer
		((ProtectorView)getProtector().getView()).fadeTo(killer);
		
		//Bullet Die
		Bullet killer_blt = (Bullet)pst.ect.blt_map.get(bulletKey);
		if(killer_blt!=null)
			killer_blt.die();
		
		killer.getProtector().plus(ptrNum);
		
		pst.ect.arranger.update();
	}
	
	public void repeat() {
		sc.cold();
		
		Pos tmpPos = new Pos(_x,_y);
		
		if(!calcer.move(tmpPos, getTargetPos(), speed)){
			return;
		}
		
		calcer.limitPos(tmpPos,this);
		/*
		 * add for 1.0.3
		 * for 1.0.4
		 */
		Wall tmpwall = (Wall) calcer.isInWall(tmpPos, this);
		if(tmpwall!=wall){
			if(tmpwall!=null){
				tmpwall.enter(this);
			}else{
				wall.exit(this);
			}
		}
		wall = tmpwall;
		
		setPos(tmpPos);
	}
	
	@Override
	public void setPos(Pos pos) {
		super.setPos(pos);
		protector.updatePos();
	}
	
	public void synchPos(Pos pos) {
//		Pos nextPos = new Pos(_x,_y);
//		calcer.move(nextPos, _rotation, speed);
		/*
		 * for v1.0.3
		 */
//		if(!calcer.limitPos(pos, this) && !calcer.limitPos(nextPos, this)){
//			if(calcer.calcDistance(pos, getPos())>Conf.tank_speed * 6)
//				setPos(pos);
//		}else{
//			if(calcer.calcDistance(pos, getPos())>Conf.tank_speed * Conf.FPS * 2){
//				setPos(pos);
//			}
//		}
		if(calcer.calcDistance(pos, getPos())>Conf.tank_speed * 9){
			setPos(pos);
		}
	}
	
	@Override
	public void fire(int key) {
		if(pst.ect.player!=null)
			Media.fire(calcer.calcDistance(getPos(), pst.ect.player.getPos()),Conf.visible_area_radium*1.5f);
		Bullet blt = new Bullet(pst,_id,key,this);
		blt.init();
		blt.moveTo(getTargetPos());
		sc.fired();
	}
	
	public void flash(){
		if(pst.ect.player!=null)
			Media.flash(calcer.calcDistance(getPos(), pst.ect.player.getPos()),Conf.visible_area_radium*1.5f);
		pst.bridge.createFlashEffect(this);
		float tmp_cos = (float)Math.cos(_rotation * Math.PI / 180);
		float tmp_sin = -(float)Math.sin(_rotation * Math.PI / 180);
		float old_x = _x;
		Pos tmp_pos = new Pos(_x,_y);
		tmp_pos.x += tmp_cos * Conf.flash_step * speed;
		tmp_pos.y += tmp_sin * Conf.flash_step * speed;
		
		if(calcer.limitPos(tmp_pos, this)){
			Pos new_pos = new Pos(_x,_y);
			for(int step=Conf.flash_step;step>0;step--){
				new_pos.x += speed * tmp_cos;
				new_pos.y += speed * tmp_sin;
				calcer.limitPos(new_pos,this);
				pos.x = new_pos.x;
				pos.y = new_pos.y;
			}
			if((new_pos.x-target.x)*(new_pos.x-old_x)>0)
				setTargetPos(new_pos);
			setPos(new_pos);
			sc.flashed();
		}else{
			System.out.println("Not Limit");
			if((tmp_pos.x-target.x)*(tmp_pos.x-old_x)>0)
				setTargetPos(tmp_pos);
			setPos(tmp_pos);
			sc.flashed();
		}
	}

	@Override
	public String toString() {
		return "Tank(x,y = "+pos+"),targetx,target_y = "+target+",rotation = "+_rotation+",target_dis="+calcer.calcDistance(pos, target)+")";
	}

	@Override
	public Protector getProtector() {
		return protector;
	}
	
	@Override
	public Tank getInstance() {
		return this;
	}
	
	public boolean isPlayer(){
		return false;
	}

}
